package com.chindeo.h5.x5.web

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context.MODE_PRIVATE
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.webkit.*
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.RelativeLayout
import com.chindeo.h5.R
import com.chindeo.h5.databinding.FmWebBinding
import com.chindeo.skin.option.bed.dynamicSkin
import com.google.gson.Gson
import com.lazylibs.component.ui.fragment.BaseVMFragment
import com.lazylibs.util.ScreenUtils
import org.json.JSONException
import org.json.JSONObject

/**H5Fragment 谷歌自带内核 封装WebView
 * Created by zqs on 2022/5/11
 */
class WebFragment : BaseVMFragment<FmWebBinding>(R.layout.fm_web), View.OnLongClickListener,
    IWebView {
    // 视频全屏参数
    private var mLayoutParams = FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
    )
    private var mVideoCallback: WebChromeClient.CustomViewCallback? = null
    private lateinit var mRootView: RelativeLayout
    private lateinit var mContentView: LinearLayout
    private lateinit var mProgressBar: ProgressBar
    private var mWebView: WebView? = null
    private var mWebSettings: WebSettings? = null
    private var mWebChromeClient: IWebChromeClient? = null
    private var mWebViewClient: WebViewClient? = null
    private var mJavaInterface: TemplateJavaInterface? = null
    private var mVideoView: View? = null
    private var mGson: Gson? = null

    companion object {
        fun newUrlInstance(url: String): WebFragment {
            val args = Bundle()
            val fragment = WebFragment()
            args.putString("url", url)
            fragment.arguments = args
            return fragment
        }

        fun newHtmlInstance(html: String): WebFragment {
            val args = Bundle()
            val fragment = WebFragment()
            args.putString("html", html)
            fragment.arguments = args
            return fragment
        }
    }


    override fun init(savedInstanceState: Bundle?) {
        mRootView = mBinding.webRootView
        mContentView = mBinding.webContentView
        mWebView = mBinding.webView
        mProgressBar = mBinding.pb
        mProgressBar.dynamicSkin(
            com.chindeo.skin.option.Attr.progressDrawable,
            R.drawable.progressbar_bg
        )
        initWebView()
        val url = arguments?.getString("url")
        val html = arguments?.getString("html")
        if (!TextUtils.isEmpty(url)) {
            mBinding.url = url
        }
        if (!TextUtils.isEmpty(html)) {
            mBinding.html = html
        }
    }

    @SuppressLint("JavascriptInterface")
    private fun initWebView() {
        //水平不显示
        mWebView?.isHorizontalScrollBarEnabled = false
        //垂直不显示
        mWebView?.isVerticalScrollBarEnabled = false
        mWebSettings = mWebView?.settings
        //不保存密码
        mWebSettings!!.savePassword = false
        // 保存表单数据
        mWebSettings!!.saveFormData = false
        // 是否应该支持使用其屏幕缩放控件和手势缩放 支持缩放，下面是前提条件
        mWebSettings!!.setSupportZoom(true)

        //设置内置的缩放控件，若为false则WebView不可缩放
        mWebSettings!!.builtInZoomControls = true
        //隐藏原生的缩放控件
        mWebSettings!!.displayZoomControls = false
        // 设置缓存模式 解决返回上一级总是会刷新
        mWebSettings!!.cacheMode = WebSettings.LOAD_NO_CACHE
        // setDefaultZoom  api19被弃用
        // 设置此属性，可任意比例缩放。 将图片调整到合适WebView的大小
        mWebSettings!!.useWideViewPort = true
        //缩放至屏幕的大小
        mWebSettings!!.loadWithOverviewMode = true
        // 不缩
        mWebView?.setInitialScale(100)
        //  页面加载好以后，再放开图片
        mWebSettings!!.blockNetworkImage = false
        // 排版适应屏幕
        mWebSettings!!.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        // WebView是否新窗口打开(加了后可能打不开网页)
        mWebSettings!!.setSupportMultipleWindows(true)
        //设置可以访问文件 设置不可以访问文件以及操作文件有安全漏洞
        mWebSettings!!.allowContentAccess = false
        //允许webview对文件的操作
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mWebSettings!!.allowUniversalAccessFromFileURLs = false
            mWebSettings!!.allowFileAccessFromFileURLs = false
        }
        mWebSettings!!.userAgentString = mWebSettings!!.userAgentString
        mWebSettings!!.pluginState = WebSettings.PluginState.ON

        //支持通过js打开新窗口
        mWebSettings!!.javaScriptCanOpenWindowsAutomatically = true
        //设置编码格式
        mWebSettings!!.defaultTextEncodingName = "utf-8"
        // webview从5.0开始默认不允许混合模式,https中不能加载http资源,需要设置开启。
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mWebSettings!!.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        }
        /** 设置字体默认缩放大小(改变网页字体大小,setTextSize  api14被弃用)  解决字体大小就只会由网页改动，不随系统变化 */
        mWebSettings!!.textZoom = 100
        mWebChromeClient = IWebChromeClient(this, requireActivity())
        mWebView?.webChromeClient = mWebChromeClient

        // 与js交互
        mWebViewClient = IWebViewClient(this)
        mWebView?.webViewClient = mWebViewClient!!
        //开启 DOM storage API 功能
        mWebSettings!!.domStorageEnabled = true
        //开启 database storage api 功能
        mWebSettings!!.databaseEnabled = true
        //开启 Application caches 功能
        mWebSettings!!.setAppCacheEnabled(true)
        val cacheDirPath = requireActivity().filesDir.absolutePath.toString() + "/web"
        //设置Application Caches 缓存目录
        mWebSettings!!.setAppCachePath(cacheDirPath)
        //设置定位的数据库路径    
        val dir = requireActivity().getDir("database", MODE_PRIVATE).path
        mWebSettings!!.setGeolocationDatabasePath(dir)
        //启用地理定位
        mWebSettings!!.setGeolocationEnabled(true)
        //支持自动加载图片
        mWebSettings!!.loadsImagesAutomatically =
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
        //WebView长按事件
        mWebView?.setOnLongClickListener(this)
        mJavaInterface = mWebView?.let { TemplateJavaInterface(requireActivity(), it) }
        mGson = Gson()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
//            mWebView?.addJavascriptInterface(mJavaInterface!!, "Android")
            mWebView?.addJavascriptInterface(mJavaInterface!!, "Chindeo")
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            try {
                //在Android17一下移除该js对象 WebView安全问题
                mWebView?.removeJavascriptInterface("accessibility")
                mWebView?.removeJavascriptInterface("accessibilityTraversal")
                mWebView?.removeJavascriptInterface("searchBoxJavaBridge_")
            } catch (e: Exception) {
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true)
        }
        mWebSettings!!.javaScriptEnabled = true
    }


    fun loadJsFunction(funName: String, param: String) {
        val url = "javascript:$funName('$param')"
        mWebView?.evaluateJavascript(url, object : ValueCallback<String?> {
            override fun onReceiveValue(value: String?) {
//            Log.d(WebFragment::javaClass.name, "ddd onReceiveValue value :$value")
            }
        })
    }

    private var onJavascriptInterfaceListener: OnJavascriptInterfaceListener? = null

    fun setOnJavascriptIListener(onJavascriptInterfaceListener: OnJavascriptInterfaceListener?) {
        this.onJavascriptInterfaceListener = onJavascriptInterfaceListener
    }

    inner class TemplateJavaInterface(val activity: Activity, val webView: WebView) {
        @JavascriptInterface
        fun onAndroidFunction(json: String?): String? {
            var returnString: String? = "success"

            // json { function: clickVoice,param{} }
            if (onJavascriptInterfaceListener != null) {
                try {
                    val jsonObject = JSONObject(json)
                    val function = jsonObject.getString("function")
                    returnString = function
                    if ("startVoice" == function) {
                        onJavascriptInterfaceListener!!.onStartVoice()
                    } else if ("stopVoice" == function) {
                        onJavascriptInterfaceListener!!.onStopVoice()
                    } else if ("voiceAnalysis" == function) {
                        val paramJson = jsonObject.getJSONObject("param")
                        onJavascriptInterfaceListener!!.onVoiceAnalysis(paramJson.toString())
                    } else if ("clickVoice" == function) {
                        onJavascriptInterfaceListener!!.onClickVoice()
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
            return returnString
        }

    }

    fun refresh() {
        mWebView?.reload()
    }

    override fun onLongClick(p0: View?): Boolean {
        val hitTestResult = mWebView?.hitTestResult
        return false
    }

    override fun title(title: String?) {

    }

    override fun progress(newProgress: Int) {
        if (newProgress == 100) {
            mProgressBar.visibility = View.GONE;//加载完网页进度条消失
        } else {
            mProgressBar.visibility = View.VISIBLE;//开始加载网页时显示进度条
            mProgressBar.progress = newProgress;//设置进度值
        }
    }

    override fun shouldOverrideUrlLoading(url: String?): Boolean {
        return false
    }

    override fun getVideoLoadingProgressView(): View? {
        val view: View = FrameLayout(requireContext())
        view.layoutParams = FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        return view
    }

    override fun onShowCustomView(view: View?, callback: WebChromeClient.CustomViewCallback?) {
        if (mVideoView != null) {
            onHideCustomView()
            return
        }
        mRootView.setBackgroundColor(Color.BLACK)
        mRootView.addView(view, mLayoutParams)
        mContentView.visibility = View.GONE
        ScreenUtils.fullScreen(requireActivity())
        mVideoView = view
        mVideoCallback = callback
    }

    override fun onHideCustomView() {
        if (mVideoView != null) {
            mRootView.setBackgroundColor(Color.WHITE)
            mRootView.removeView(mVideoView)
            mContentView.visibility = View.VISIBLE
            ScreenUtils.resetScreen(requireActivity())
            mVideoView = null
            if (mVideoCallback != null) {
                mVideoCallback!!.onCustomViewHidden()
            }
            mVideoCallback = null
        }
    }

    override fun onResume() {
        mWebSettings!!.javaScriptEnabled = true
        mWebView?.onResume()
        mWebView?.resumeTimers()
        super.onResume()
    }

    override fun onPause() {
        mWebSettings!!.javaScriptEnabled = false
        mWebView?.onPause()
        mWebView?.pauseTimers()
        super.onPause()
    }

    override fun onDestroy() {
        mWebView?.destroy()
        super.onDestroy()
    }


}